library(ggplot2)
package ‘ggplot2’ was built under R version 3.6.2
library(CodeClanData)
Attaching package: ‘CodeClanData’
The following object is masked from ‘package:datasets’:
volcano
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
[37m── [1mAttaching packages[22m ───────────────────────────────────────────────────── tidyverse 1.3.0 ──[39m
[37m[32m✓[37m [34mtibble [37m 3.0.3 [32m✓[37m [34mdplyr [37m 1.0.0
[32m✓[37m [34mtidyr [37m 1.1.0 [32m✓[37m [34mstringr[37m 1.4.0
[32m✓[37m [34mreadr [37m 1.3.1 [32m✓[37m [34mforcats[37m 0.5.0
[32m✓[37m [34mpurrr [37m 0.3.4 [39m
package ‘tibble’ was built under R version 3.6.2package ‘tidyr’ was built under R version 3.6.2package ‘purrr’ was built under R version 3.6.2package ‘dplyr’ was built under R version 3.6.2[37m── [1mConflicts[22m ──────────────────────────────────────────────────────── tidyverse_conflicts() ──
[31mx[37m [34mdplyr[37m::[32mfilter()[37m masks [34mstats[37m::filter()
[31mx[37m [34mdplyr[37m::[32mlag()[37m masks [34mstats[37m::lag()[39m
library(ggthemes)
library(viridis)
Loading required package: viridisLite
COMPARISON
Create a suitable plot for the following three datasets:
late_deliveries
Late Deliveries
ggplot(late_deliveries) +
aes(x = date, y = late_deliveries, fill = late_deliveries, bins = 20) +
geom_col(position = "dodge") +
scale_fill_distiller(palette = "Pastel2") +
theme_bw() +
labs(
x = "Date",
y = "late deliveries",
title = "Late Deliveries"
) +
theme(title = element_text(size = 16, face = "italic", colour = "Blue"))

solution 2
ggplot(late_deliveries) +
aes(x = date, y = late_deliveries) +
geom_line() +
geom_point() +
labs(x = "year", y = "number of late deliveries") +
theme_minimal()

Recovery time
recovery_times
ggplot(recovery_times) +
aes(x = recovery, y = prognosis, fill = treatment_group) +
geom_col(position = "dodge") +
scale_fill_hue(h = c(120,300), c = 40, l = 45) +
theme_classic(11) +
labs(
x = "Recovery",
y = "Prognosis",
title = "Recovery Times"
) +
theme(
title = element_text(size = 15, face = "bold", colour = "blue"),
panel.background = element_rect(fill = "Pink"),
panel.grid = element_blank(),
plot.title = element_text(size = 15, face = "bold", colour = "blue")
)

NA
NA
solution 2
ggplot(recovery_times) +
aes(x = treatment_group, y = recovery, fill = prognosis) +
geom_col(position = "dodge") +
labs(x = "\n Treatment Group", y = "Recovery time (months) \n") +
scale_fill_colorblind()

NA
NA
Fitness Level
fitness_levels
ggplot(fitness_levels) +
aes(x = age, y = fitness_score, colour = group) +
geom_line() +
theme_light() +
facet_wrap(~ group, ncol = 10, scales = "free") +
scale_color_gradient2_tableau()

NA
NA
Solution 2
ggplot(fitness_levels) +
aes(x = age, y = fitness_score, group = child, color = child) +
geom_line() +
geom_point() +
facet_wrap(~ group, ncol = 5) +
labs(y = "fitness score \n", x = "\n age (years)", title = "Individual child fitness score by Group") +
scale_colour_hue(guide = guide_legend(nrow = 10, byrow = TRUE))

CONNECTION
Blood Pressure
ggplot(blood_pressure) +
aes(x = systolic_blood_pressure_mm_hg, y = daily_saturated_fat_intake_mg, colour = daily_saturated_fat_intake_mg) +
geom_point() +
scale_colour_gradient2(low = "blue", high = "red", mid = "white", midpoint = 15) +
labs(
x = "Sys Blood Pre",
y = "Daily fat intake (mg)",
title = "Blood Pressue",
subtitle = "fat Intake (mg)"
) +
theme_light()

Solution 2
ggplot(blood_pressure) +
aes(
x = daily_saturated_fat_intake_mg,
y = systolic_blood_pressure_mm_hg
) +
geom_point() +
labs(x = "daily fat intake (mg)", y = "systolic blood pressure (mmHg)")

Car use
car_use
ggplot(car_use) +
aes(x = city, y = population, colour = car_use_percent) +
geom_point() +
scale_color_distiller(palette = "PuOr") +
theme_dark() +
labs(
title = "Car Use",
subtitle = "Car use"
)

NA
NA
NA
solution 2
ggplot(car_use) +
aes(
x = car_use_percent,
y = air_so2_concentration_ppm,
size = population
) +
geom_point(alpha = 0.5) +
labs(x = "car use (%)", y = "air CO2 concentration (ppm)")

DISTRIBUTION
D20 Outcome
ggplot(d20_outcomes) +
aes(x = outcome) +
geom_histogram(bins = 20, col = "white")

solution 2
ggplot(d20_outcomes) +
aes(x = outcome) +
geom_density()

COMPOSITION
Pension Surplus
ggplot(pension_surplus) +
aes(x = item, y = balance, fill = balance > 0) +
geom_col() +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
coord_flip()

Pension Liabilities
ggplot(pension_liabilities) +
aes(x = year, y = liability_millions, fill = liability_type) +
geom_col() +
scale_fill_colorblind()

Homework part 1
library(ggplot2)
library(CodeClanData)
library(dplyr)
- Take the data in the dataset qb_revenue_breakdown and make a stacked bar chart showing the sources of revenue across the two years in the dataset.
ggplot(qb_revenue_breakdown) +
aes(x = Year, y = Revenue, fill = Product) +
geom_col()

- Make a line chart showing monthly sales of the “flagship product” - the KwikBit Unit1 - over the last year. This data is inside qb_monthly_sales, but you will need to use subset.
kwikbit_sales <- subset(qb_monthly_sales, Cashflow == "Kwikbit Unit 1 Sales")
ggplot(kwikbit_sales) +
aes(x = Date, y = Amount) +
geom_line()

- Make a line chart showing monthly revenue and costs over the last year. This data is also in qb_monthly_sales.
revenue_and_costs <- subset(qb_monthly_sales, Cashflow != "Kwikbit Unit 1 Sales")
ggplot(revenue_and_costs) +
aes(x = Date, y = Amount, colour = Cashflow) +
geom_line()

- Show annual sales of personal fitness trackers over the last 5 years broken down by company as a ribbon plot (use geom_area). This data is in qb_competitors.
ggplot(qb_competitors) +
aes(x = Year, y = Revenue, fill = Company) +
geom_area()

- Now show the sales from the 5 competitors as a line graph. Include an extra layer that shows the data points used to make the lines.
ggplot(qb_competitors) +
aes(x = Year, y = Revenue, colour = Company) +
geom_line() +
geom_point()

- Now the company wants to compare the number of steps that their device counts vs. their competitors. Make a line graph of the number of steps throughout time, and use faceting to compare between individuals and people. Data is in qb_device_data.
qb_device_data <-
mutate(qb_device_data, decimal_hour = hours + (mins/60))
ggplot(qb_device_data) +
aes(x = decimal_hour, y = counts) +
geom_line() +
facet_grid(id ~ device)

Take the plots that you produced in part one and now polish them by:
Adding appropriate labels Changing the scales and coordinates when appropriate. Applying a unified theme, which is described below: Graphs should have white backgrounds, and use colour sparingly. There should be faint grid lines. Font sizes should be ~12pt although titles should be slightly larger and axis labels can be slightly smaller. All plots should use colours from the following company colour scheme.
col_scheme <- c("#E89FE9", "#50434F", "#B6A7B5", "#F9A472", "#BD7040")
theme_qb <-
theme(
text = element_text(size = 12),
title = element_text(size = 14),
axis.text = element_text(size = 10),
panel.background = element_rect(fill = "white"),
panel.grid = element_line(colour = "grey90", linetype = "dashed")
)
ggplot(qb_revenue_breakdown) +
aes(x = Year, y = Revenue, fill = Product) +
geom_col() +
scale_fill_manual(values = col_scheme) +
ggtitle(
"Breakdown of QikBit Revenue by Product Line",
subtitle = "2018 and 2019"
) +
theme_qb

kwikbit_sales <- subset(qb_monthly_sales, Cashflow == "Kwikbit Unit 1 Sales")
ggplot(kwikbit_sales) +
aes(x = Date, y = Amount, group = Cashflow) +
geom_line(size = 2, colour = col_scheme[3]) +
theme_qb +
scale_y_continuous("Sales", labels = scales::dollar_format(prefix = "£")) +
ggtitle("Sales of Kwikbit Unit1", subtitle = "1 Aug 2018 to 1 July 2019")

revenue_and_costs <- subset(qb_monthly_sales, Cashflow != "Kwikbit Unit 1 Sales")
ggplot(revenue_and_costs) +
aes(x = Date, y = Amount, colour = Cashflow, group = Cashflow) +
geom_line(size = 2) +
theme_qb +
scale_colour_manual(values = col_scheme) +
scale_y_continuous("Sales", labels = scales::dollar_format(prefix = "£")) +
ggtitle("QikBit - Revenue and Costs", subtitle = "1 Aug 2018 to 1 July 2019")

ggplot(qb_competitors) +
aes(x = Year, y = Revenue, fill = Company) +
geom_area() +
scale_y_continuous(labels = scales::dollar) +
theme_qb +
scale_fill_manual(values = col_scheme) +
ggtitle(
"Revenue in the Fitness Tracker Market by Company",
subtitle = "2015 - 2019"
)

ggplot(qb_competitors) +
aes(x = Year, y = Revenue, colour = Company) +
geom_line() +
geom_point() +
scale_y_continuous(labels = scales::dollar) +
theme_qb +
scale_colour_manual(values = col_scheme) +
ggtitle(
"Revenue in the Fitness Tracker Market by Company",
subtitle = "2015 - 2019"
)

ggplot(qb_device_data) +
aes(x = decimal_hour, y = counts, colour = device) +
geom_line() +
scale_x_continuous("Time (hours)") +
scale_y_continuous("Steps") +
facet_grid(id ~ device) +
scale_colour_manual(values = col_scheme) +
theme_qb +
ggtitle("Comparison between KwikBit Unit1 and Competitors for 5 individuals")

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoQ29kZUNsYW5EYXRhKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeSh2aXJpZGlzKQpgYGAKCkNPTVBBUklTT04KCkNyZWF0ZSBhIHN1aXRhYmxlIHBsb3QgZm9yIHRoZSBmb2xsb3dpbmcgdGhyZWUgZGF0YXNldHM6CgoKYGBge3J9CgpsYXRlX2RlbGl2ZXJpZXMKYGBgCgpMYXRlIERlbGl2ZXJpZXMKCmBgYHtyfQpnZ3Bsb3QobGF0ZV9kZWxpdmVyaWVzKSArCiBhZXMoeCA9IGRhdGUsIHkgPSBsYXRlX2RlbGl2ZXJpZXMsIGZpbGwgPSBsYXRlX2RlbGl2ZXJpZXMsIGJpbnMgPSAyMCkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGUgPSAiUGFzdGVsMiIpICsKICB0aGVtZV9idygpICsgCiAgbGFicygKICAgIHggPSAiRGF0ZSIsCiAgICB5ID0gImxhdGUgZGVsaXZlcmllcyIsCiAgICB0aXRsZSA9ICJMYXRlIERlbGl2ZXJpZXMiCiAgKSArICAKICB0aGVtZSh0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYsIGZhY2UgPSAiaXRhbGljIiwgY29sb3VyID0gIkJsdWUiKSkKCmBgYAoKc29sdXRpb24gMgoKYGBge3J9CgpnZ3Bsb3QobGF0ZV9kZWxpdmVyaWVzKSArCiAgYWVzKHggPSBkYXRlLCB5ID0gbGF0ZV9kZWxpdmVyaWVzKSArCiAgZ2VvbV9saW5lKCkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBsYWJzKHggPSAieWVhciIsIHkgPSAibnVtYmVyIG9mIGxhdGUgZGVsaXZlcmllcyIpICsgCiAgdGhlbWVfbWluaW1hbCgpCgpgYGAKClJlY292ZXJ5IHRpbWUKCmBgYHtyfQoKcmVjb3ZlcnlfdGltZXMKYGBgCgoKYGBge3J9CmdncGxvdChyZWNvdmVyeV90aW1lcykgKwogIGFlcyh4ID0gcmVjb3ZlcnksIHkgPSBwcm9nbm9zaXMsIGZpbGwgPSB0cmVhdG1lbnRfZ3JvdXApICsgCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgc2NhbGVfZmlsbF9odWUoaCA9IGMoMTIwLDMwMCksIGMgPSA0MCwgbCA9IDQ1KSArCiAgdGhlbWVfY2xhc3NpYygxMSkgKwogIGxhYnMoCiAgICB4ID0gIlJlY292ZXJ5IiwKICAgIHkgPSAiUHJvZ25vc2lzIiwKICAgIHRpdGxlID0gIlJlY292ZXJ5IFRpbWVzIgogICkgKwogIHRoZW1lKAogICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiLCBjb2xvdXIgPSAiYmx1ZSIpLAogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIlBpbmsiKSwgCiAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAiYm9sZCIsIGNvbG91ciA9ICJibHVlIikKICApCiAgCgpgYGAKCnNvbHV0aW9uIDIKCmBgYHtyfQpnZ3Bsb3QocmVjb3ZlcnlfdGltZXMpICsKICBhZXMoeCA9IHRyZWF0bWVudF9ncm91cCwgeSA9IHJlY292ZXJ5LCBmaWxsID0gcHJvZ25vc2lzKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArIAogIGxhYnMoeCA9ICJcbiBUcmVhdG1lbnQgR3JvdXAiLCB5ID0gIlJlY292ZXJ5IHRpbWUgKG1vbnRocykgXG4iKSArIAogICAgc2NhbGVfZmlsbF9jb2xvcmJsaW5kKCkKCgpgYGAKCiBGaXRuZXNzIExldmVsCiAKYGBge3J9CmZpdG5lc3NfbGV2ZWxzCmBgYAoKCmBgYHtyfQoKZ2dwbG90KGZpdG5lc3NfbGV2ZWxzKSArIAogIGFlcyh4ID0gYWdlLCB5ID0gZml0bmVzc19zY29yZSwgY29sb3VyID0gZ3JvdXApICsKICBnZW9tX2xpbmUoKSArCiAgdGhlbWVfbGlnaHQoKSArIAogIGZhY2V0X3dyYXAofiBncm91cCwgbmNvbCA9IDEwLCBzY2FsZXMgPSAiZnJlZSIpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudDJfdGFibGVhdSgpCgoKYGBgCgpTb2x1dGlvbiAyCgpgYGB7cn0KZ2dwbG90KGZpdG5lc3NfbGV2ZWxzKSArCiAgYWVzKHggPSBhZ2UsIHkgPSBmaXRuZXNzX3Njb3JlLCBncm91cCA9IGNoaWxkLCBjb2xvciA9IGNoaWxkKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgZmFjZXRfd3JhcCh+IGdyb3VwLCBuY29sID0gNSkgKyAKICBsYWJzKHkgPSAiZml0bmVzcyBzY29yZSBcbiIsIHggPSAiXG4gYWdlICh5ZWFycykiLCB0aXRsZSA9ICJJbmRpdmlkdWFsIGNoaWxkIGZpdG5lc3Mgc2NvcmUgYnkgR3JvdXAiKSArIAogIHNjYWxlX2NvbG91cl9odWUoZ3VpZGUgPSBndWlkZV9sZWdlbmQobnJvdyA9IDEwLCBieXJvdyA9IFRSVUUpKQoKYGBgCgoKCkNPTk5FQ1RJT04KCkJsb29kIFByZXNzdXJlCgpgYGB7cn0KZ2dwbG90KGJsb29kX3ByZXNzdXJlKSArCiAgYWVzKHggPSBzeXN0b2xpY19ibG9vZF9wcmVzc3VyZV9tbV9oZywgeSA9IGRhaWx5X3NhdHVyYXRlZF9mYXRfaW50YWtlX21nLCBjb2xvdXIgPSBkYWlseV9zYXR1cmF0ZWRfZmF0X2ludGFrZV9tZykgKwogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsIGhpZ2ggPSAicmVkIiwgbWlkID0gIndoaXRlIiwgbWlkcG9pbnQgPSAxNSkgKwogIGxhYnMoCiAgICB4ID0gIlN5cyBCbG9vZCBQcmUiLAogICAgeSA9ICJEYWlseSBmYXQgaW50YWtlIChtZykiLAogICAgdGl0bGUgPSAiQmxvb2QgUHJlc3N1ZSIsCiAgICBzdWJ0aXRsZSA9ICJmYXQgSW50YWtlIChtZykiCiAgKSArIAogIHRoZW1lX2xpZ2h0KCkKYGBgCgpTb2x1dGlvbiAyCgpgYGB7cn0KZ2dwbG90KGJsb29kX3ByZXNzdXJlKSArCiAgYWVzKAogICAgeCA9IGRhaWx5X3NhdHVyYXRlZF9mYXRfaW50YWtlX21nLAogICAgeSA9IHN5c3RvbGljX2Jsb29kX3ByZXNzdXJlX21tX2hnCiAgKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4ID0gImRhaWx5IGZhdCBpbnRha2UgKG1nKSIsIHkgPSAic3lzdG9saWMgYmxvb2QgcHJlc3N1cmUgKG1tSGcpIikKYGBgCgpDYXIgdXNlCgpgYGB7cn0KY2FyX3VzZQpgYGAKCgoKYGBge3J9CmdncGxvdChjYXJfdXNlKSArCiAgYWVzKHggPSBjaXR5LCB5ID0gcG9wdWxhdGlvbiwgY29sb3VyID0gY2FyX3VzZV9wZXJjZW50KSArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV9jb2xvcl9kaXN0aWxsZXIocGFsZXR0ZSA9ICJQdU9yIikgKwogIHRoZW1lX2RhcmsoKSArCiAgbGFicygKICAgIHRpdGxlID0gIkNhciBVc2UiLCAKICAgIHN1YnRpdGxlID0gIkNhciB1c2UiCiAgKQogIAogIAoKYGBgCgpzb2x1dGlvbiAyCgpgYGB7cn0KZ2dwbG90KGNhcl91c2UpICsKICBhZXMoCiAgICB4ID0gY2FyX3VzZV9wZXJjZW50LAogICAgeSA9IGFpcl9zbzJfY29uY2VudHJhdGlvbl9wcG0sCiAgICBzaXplID0gcG9wdWxhdGlvbgogICkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsgCiAgbGFicyh4ID0gImNhciB1c2UgKCUpIiwgeSA9ICJhaXIgQ08yIGNvbmNlbnRyYXRpb24gKHBwbSkiKQoKYGBgCgoKRElTVFJJQlVUSU9OCgpEMjAgT3V0Y29tZQoKYGBge3J9CmdncGxvdChkMjBfb3V0Y29tZXMpICsKICBhZXMoeCA9IG91dGNvbWUpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMjAsIGNvbCA9ICJ3aGl0ZSIpIAoKYGBgCnNvbHV0aW9uIDIKCmBgYHtyfQpnZ3Bsb3QoZDIwX291dGNvbWVzKSArCiAgYWVzKHggPSBvdXRjb21lKSArCiAgZ2VvbV9kZW5zaXR5KCkKCmBgYAoKCgpDT01QT1NJVElPTgoKUGVuc2lvbiBTdXJwbHVzCgpgYGB7cn0KZ2dwbG90KHBlbnNpb25fc3VycGx1cykgKwogIGFlcyh4ID0gaXRlbSwgeSA9IGJhbGFuY2UsIGZpbGwgPSBiYWxhbmNlID4gMCkgKwogIGdlb21fY29sKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICsgCiAgY29vcmRfZmxpcCgpIAoKYGBgCgoKUGVuc2lvbiBMaWFiaWxpdGllcwoKYGBge3J9CmdncGxvdChwZW5zaW9uX2xpYWJpbGl0aWVzKSArCiAgYWVzKHggPSB5ZWFyLCB5ID0gbGlhYmlsaXR5X21pbGxpb25zLCBmaWxsID0gbGlhYmlsaXR5X3R5cGUpICsKICBnZW9tX2NvbCgpICsgCiAgc2NhbGVfZmlsbF9jb2xvcmJsaW5kKCkKCmBgYAoKCkhvbWV3b3JrIHBhcnQgMQoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShDb2RlQ2xhbkRhdGEpCmxpYnJhcnkoZHBseXIpCgpgYGAKCgoxLiBUYWtlIHRoZSBkYXRhIGluIHRoZSBkYXRhc2V0IHFiX3JldmVudWVfYnJlYWtkb3duIGFuZCBtYWtlIGEgc3RhY2tlZCBiYXIgY2hhcnQgc2hvd2luZyB0aGUgc291cmNlcyBvZiByZXZlbnVlIGFjcm9zcyB0aGUgdHdvIHllYXJzIGluIHRoZSBkYXRhc2V0LgoKYGBge3J9CmdncGxvdChxYl9yZXZlbnVlX2JyZWFrZG93bikgKwogIGFlcyh4ID0gWWVhciwgeSA9IFJldmVudWUsIGZpbGwgPSBQcm9kdWN0KSArCiAgZ2VvbV9jb2woKQoKYGBgCgoyLiBNYWtlIGEgbGluZSBjaGFydCBzaG93aW5nIG1vbnRobHkgc2FsZXMgb2YgdGhlIOKAnGZsYWdzaGlwIHByb2R1Y3TigJ0gLSB0aGUgS3dpa0JpdCBVbml0MSAtIG92ZXIgdGhlIGxhc3QgeWVhci4gVGhpcyBkYXRhIGlzIGluc2lkZSBxYl9tb250aGx5X3NhbGVzLCBidXQgeW91IHdpbGwgbmVlZCB0byB1c2Ugc3Vic2V0LgoKYGBge3J9Cgprd2lrYml0X3NhbGVzIDwtIHN1YnNldChxYl9tb250aGx5X3NhbGVzLCBDYXNoZmxvdyA9PSAiS3dpa2JpdCBVbml0IDEgU2FsZXMiKQoKZ2dwbG90KGt3aWtiaXRfc2FsZXMpICsKICBhZXMoeCA9IERhdGUsIHkgPSBBbW91bnQpICsKICBnZW9tX2xpbmUoKSAKYGBgCgozLiBNYWtlIGEgbGluZSBjaGFydCBzaG93aW5nIG1vbnRobHkgcmV2ZW51ZSBhbmQgY29zdHMgb3ZlciB0aGUgbGFzdCB5ZWFyLiBUaGlzIGRhdGEgaXMgYWxzbyBpbiBxYl9tb250aGx5X3NhbGVzLgoKYGBge3J9CnJldmVudWVfYW5kX2Nvc3RzIDwtIHN1YnNldChxYl9tb250aGx5X3NhbGVzLCBDYXNoZmxvdyAhPSAiS3dpa2JpdCBVbml0IDEgU2FsZXMiKQoKZ2dwbG90KHJldmVudWVfYW5kX2Nvc3RzKSArCiAgYWVzKHggPSBEYXRlLCB5ID0gQW1vdW50LCBjb2xvdXIgPSBDYXNoZmxvdykgKwogIGdlb21fbGluZSgpCgpgYGAKCgo0LiBTaG93IGFubnVhbCBzYWxlcyBvZiBwZXJzb25hbCBmaXRuZXNzIHRyYWNrZXJzIG92ZXIgdGhlIGxhc3QgNSB5ZWFycyBicm9rZW4gZG93biBieSBjb21wYW55IGFzIGEgcmliYm9uIHBsb3QgKHVzZSBnZW9tX2FyZWEpLiBUaGlzIGRhdGEgaXMgaW4gcWJfY29tcGV0aXRvcnMuCgpgYGB7cn0KZ2dwbG90KHFiX2NvbXBldGl0b3JzKSArCiAgYWVzKHggPSBZZWFyLCB5ID0gUmV2ZW51ZSwgZmlsbCA9IENvbXBhbnkpICsKICBnZW9tX2FyZWEoKSAKCmBgYAoKCgo1LiBOb3cgc2hvdyB0aGUgc2FsZXMgZnJvbSB0aGUgNSBjb21wZXRpdG9ycyBhcyBhIGxpbmUgZ3JhcGguIEluY2x1ZGUgYW4gZXh0cmEgbGF5ZXIgdGhhdCBzaG93cyB0aGUgZGF0YSBwb2ludHMgdXNlZCB0byBtYWtlIHRoZSBsaW5lcy4KCmBgYHtyfQpnZ3Bsb3QocWJfY29tcGV0aXRvcnMpICsKICBhZXMoeCA9IFllYXIsIHkgPSBSZXZlbnVlLCBjb2xvdXIgPSBDb21wYW55KSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKQoKYGBgCgo2LiBOb3cgdGhlIGNvbXBhbnkgd2FudHMgdG8gY29tcGFyZSB0aGUgbnVtYmVyIG9mIHN0ZXBzIHRoYXQgdGhlaXIgZGV2aWNlIGNvdW50cyB2cy4gdGhlaXIgY29tcGV0aXRvcnMuIE1ha2UgYSBsaW5lIGdyYXBoIG9mIHRoZSBudW1iZXIgb2Ygc3RlcHMgdGhyb3VnaG91dCB0aW1lLCBhbmQgdXNlIGZhY2V0aW5nIHRvIGNvbXBhcmUgYmV0d2VlbiBpbmRpdmlkdWFscyBhbmQgcGVvcGxlLiBEYXRhIGlzIGluIHFiX2RldmljZV9kYXRhLgoKYGBge3J9CnFiX2RldmljZV9kYXRhIDwtIAptdXRhdGUocWJfZGV2aWNlX2RhdGEsIGRlY2ltYWxfaG91ciA9IGhvdXJzICsgKG1pbnMvNjApKQoKZ2dwbG90KHFiX2RldmljZV9kYXRhKSArCiAgYWVzKHggPSBkZWNpbWFsX2hvdXIsIHkgPSBjb3VudHMpICsKICBnZW9tX2xpbmUoKSArIAogIGZhY2V0X2dyaWQoaWQgfiBkZXZpY2UpCgpgYGAKCgpUYWtlIHRoZSBwbG90cyB0aGF0IHlvdSBwcm9kdWNlZCBpbiBwYXJ0IG9uZSBhbmQgbm93IHBvbGlzaCB0aGVtIGJ5OgoKQWRkaW5nIGFwcHJvcHJpYXRlIGxhYmVscwpDaGFuZ2luZyB0aGUgc2NhbGVzIGFuZCBjb29yZGluYXRlcyB3aGVuIGFwcHJvcHJpYXRlLgpBcHBseWluZyBhIHVuaWZpZWQgdGhlbWUsIHdoaWNoIGlzIGRlc2NyaWJlZCBiZWxvdzoKR3JhcGhzIHNob3VsZCBoYXZlIHdoaXRlIGJhY2tncm91bmRzLCBhbmQgdXNlIGNvbG91ciBzcGFyaW5nbHkuClRoZXJlIHNob3VsZCBiZSBmYWludCBncmlkIGxpbmVzLgpGb250IHNpemVzIHNob3VsZCBiZSB+MTJwdCBhbHRob3VnaCB0aXRsZXMgc2hvdWxkIGJlIHNsaWdodGx5IGxhcmdlciBhbmQgYXhpcyBsYWJlbHMgY2FuIGJlIHNsaWdodGx5IHNtYWxsZXIuCkFsbCBwbG90cyBzaG91bGQgdXNlIGNvbG91cnMgZnJvbSB0aGUgZm9sbG93aW5nIGNvbXBhbnkgY29sb3VyIHNjaGVtZS4KCgpgYGB7cn0KY29sX3NjaGVtZSA8LSBjKCIjRTg5RkU5IiwgIiM1MDQzNEYiLCAiI0I2QTdCNSIsICIjRjlBNDcyIiwgIiNCRDcwNDAiKQp0aGVtZV9xYiA8LSAKICB0aGVtZSgKICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIpLAogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JleTkwIiwgbGluZXR5cGUgPSAiZGFzaGVkIikKICApCmdncGxvdChxYl9yZXZlbnVlX2JyZWFrZG93bikgKwogIGFlcyh4ID0gWWVhciwgeSA9IFJldmVudWUsIGZpbGwgPSBQcm9kdWN0KSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sX3NjaGVtZSkgKwogIGdndGl0bGUoCiAgICAiQnJlYWtkb3duIG9mIFFpa0JpdCBSZXZlbnVlIGJ5IFByb2R1Y3QgTGluZSIsCiAgICBzdWJ0aXRsZSA9ICAiMjAxOCBhbmQgMjAxOSIKICApICsKICB0aGVtZV9xYgpgYGAKCmBgYHtyfQoKa3dpa2JpdF9zYWxlcyA8LSBzdWJzZXQocWJfbW9udGhseV9zYWxlcywgQ2FzaGZsb3cgPT0gIkt3aWtiaXQgVW5pdCAxIFNhbGVzIikKCmdncGxvdChrd2lrYml0X3NhbGVzKSArCiAgYWVzKHggPSBEYXRlLCB5ID0gQW1vdW50LCBncm91cCA9IENhc2hmbG93KSArCiAgZ2VvbV9saW5lKHNpemUgPSAyLCBjb2xvdXIgPSBjb2xfc2NoZW1lWzNdKSArCiAgdGhlbWVfcWIgKwogIHNjYWxlX3lfY29udGludW91cygiU2FsZXMiLCBsYWJlbHMgPSBzY2FsZXM6OmRvbGxhcl9mb3JtYXQocHJlZml4ID0gIsKjIikpICsKICBnZ3RpdGxlKCJTYWxlcyBvZiBLd2lrYml0IFVuaXQxIiwgc3VidGl0bGUgPSAiMSBBdWcgMjAxOCB0byAxIEp1bHkgMjAxOSIpCgpgYGAKCgpgYGB7cn0KcmV2ZW51ZV9hbmRfY29zdHMgPC0gc3Vic2V0KHFiX21vbnRobHlfc2FsZXMsIENhc2hmbG93ICE9ICJLd2lrYml0IFVuaXQgMSBTYWxlcyIpCgpnZ3Bsb3QocmV2ZW51ZV9hbmRfY29zdHMpICsKICBhZXMoeCA9IERhdGUsIHkgPSBBbW91bnQsIGNvbG91ciA9IENhc2hmbG93LCBncm91cCA9IENhc2hmbG93KSArCiAgZ2VvbV9saW5lKHNpemUgPSAyKSArCiAgdGhlbWVfcWIgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY29sX3NjaGVtZSkgKwogIHNjYWxlX3lfY29udGludW91cygiU2FsZXMiLCBsYWJlbHMgPSBzY2FsZXM6OmRvbGxhcl9mb3JtYXQocHJlZml4ID0gIsKjIikpICsKICBnZ3RpdGxlKCJRaWtCaXQgLSBSZXZlbnVlIGFuZCBDb3N0cyIsIHN1YnRpdGxlID0gIjEgQXVnIDIwMTggdG8gMSBKdWx5IDIwMTkiKQoKYGBgCgoKCmBgYHtyfQpnZ3Bsb3QocWJfY29tcGV0aXRvcnMpICsKICBhZXMoeCA9IFllYXIsIHkgPSBSZXZlbnVlLCBmaWxsID0gQ29tcGFueSkgKwogIGdlb21fYXJlYSgpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpkb2xsYXIpICsKICB0aGVtZV9xYiArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sX3NjaGVtZSkgKwogIGdndGl0bGUoCiAgICAiUmV2ZW51ZSBpbiB0aGUgRml0bmVzcyBUcmFja2VyIE1hcmtldCBieSBDb21wYW55IiwKICAgIHN1YnRpdGxlID0gIjIwMTUgLSAyMDE5IgogICkKCmBgYAoKCmBgYHtyfQpnZ3Bsb3QocWJfY29tcGV0aXRvcnMpICsKICBhZXMoeCA9IFllYXIsIHkgPSBSZXZlbnVlLCBjb2xvdXIgPSBDb21wYW55KSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6ZG9sbGFyKSArCiAgdGhlbWVfcWIgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY29sX3NjaGVtZSkgKwogIGdndGl0bGUoCiAgICAiUmV2ZW51ZSBpbiB0aGUgRml0bmVzcyBUcmFja2VyIE1hcmtldCBieSBDb21wYW55IiwKICAgIHN1YnRpdGxlID0gIjIwMTUgLSAyMDE5IgogICkKCmBgYAoKCmBgYHtyfQpnZ3Bsb3QocWJfZGV2aWNlX2RhdGEpICsKICBhZXMoeCA9IGRlY2ltYWxfaG91ciwgeSA9IGNvdW50cywgY29sb3VyID0gZGV2aWNlKSArCiAgZ2VvbV9saW5lKCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoIlRpbWUgKGhvdXJzKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoIlN0ZXBzIikgKwogIGZhY2V0X2dyaWQoaWQgfiBkZXZpY2UpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGNvbF9zY2hlbWUpICsKICB0aGVtZV9xYiArCiAgZ2d0aXRsZSgiQ29tcGFyaXNvbiBiZXR3ZWVuIEt3aWtCaXQgVW5pdDEgYW5kIENvbXBldGl0b3JzIGZvciA1IGluZGl2aWR1YWxzIikKCmBgYAoK